package OrderService

import (
	"context"
	"errors"
	"gdshop-admin-go-api/app/entity"
	"gdshop-admin-go-api/app/request/OrderReq"
	"gdshop-admin-go-api/library/response"
	"gdshop-admin-go-api/library/tools"
	toolsDb "gdshop-admin-go-api/library/tools/db"
	"gdshop-admin-go-api/library/tools/wxpayHelper"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
	"github.com/shenghui0779/gochat/mch"
	"github.com/syyongx/php2go"
	"time"
)

func MemberPay(ctx context.Context, params *OrderReq.MemberPay) *response.JsonResponse {
	var orderModel *entity.Order
	err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "order").Where(
		"id=? AND member_id=?",
		params.OrderId,
		params.MemberId,
	).Struct(&orderModel)
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}
	if orderModel == nil {
		return response.FailByRequestMessage(nil, "找不到订单")
	}
	if orderModel.Status != 1 {
		return response.FailByRequestMessage(nil, "当前订单状态不允许支付")
	}
	closeNoPayOrderDelayTime := g.Cfg().GetInt64("queue.CloseNoPayOrder.delayTime")
	if ((closeNoPayOrderDelayTime * 60) - (time.Now().Unix() - int64(orderModel.CreateAt))) < 1 {
		return response.FailByRequestMessage(nil, "订单已过期")
	}

	// 判断支付类型
	if params.Payment == "balance" {
		jieguo := ChangeStatus(ctx, &OrderReq.ChangeStatus{
			Type:     "member_pay",
			OrderId:  params.OrderId,
			Payment:  params.Payment,
			MemberId: params.MemberId,
		})
		return jieguo
	}
	// 微信支付
	if params.Payment == "wechatpay" {
		data, err := memberWechatPay(ctx, orderModel, "JSAPI")
		if err != nil {
			errorMsg := err.Error()
			if errorMsg == "getOpenId" {
				return response.JsonByAll(nil, 10004, "请先绑定微信")
			} else {
				return response.FailByRequestMessage(nil, err.Error())
			}
		}
		return response.SuccessByRequestMessageData(nil, "成功", data)
	}
	// 支付宝
	if params.Payment == "alipay" {
		data, err := memberAlipay(ctx, orderModel, "H5")
		if err != nil {
			errorMsg := err.Error()
			if errorMsg == "getOpenId" {
				return response.JsonByAll(nil, 10004, "请先绑定微信")
			} else {
				return response.FailByRequestMessage(nil, err.Error())
			}
		}
		return response.SuccessByRequestMessageData(nil, "成功", data)
	}
	return response.FailByRequestMessage(nil, "目前不支持该支付方式")
}

func memberWechatPay(ctx context.Context, orderModel *entity.Order, tradeType string) (map[string]string, error) {
	allowTradeTypes := []string{
		"JSAPI",
		"APP",
	}

	if !php2go.InArray(tradeType, allowTradeTypes) {
		return nil, errors.New("当前不支持该 tradeType:" + tradeType)
	}

	wxpay := wxpayHelper.GetWxpay(false)

	// 当前只支持 JSAPI (公众号内和小程序)方式，后续增加 APP 方式
	tradeType = "JSAPI"

	outTradeNO := gconv.String(orderModel.Id) + "F" + gconv.String(tools.MakeTimestamp())

	data := mch.OrderData{
		OutTradeNO:     outTradeNO,
		TotalFee:       gconv.Int(orderModel.TotalPrice),
		SpbillCreateIP: "127.0.0.1",
		TradeType:      tradeType,
		Body:           "订单：" + orderModel.OrderNo,
		NotifyURL:      g.Cfg().GetString("pay.wechatpay.notifyURL"),
	}

	// JSAPI 方式需要取出 openId
	if tradeType == "JSAPI" {
		var mwModel *entity.MemberWechat
		err := toolsDb.GetUnSafaTable(ctx, "member_wechat").
			Where("member_id", orderModel.MemberId).Struct(&mwModel)
		if err != nil {
			return nil, errors.New("未找到会员相应的微信登陆信息01")
		}
		if mwModel == nil {
			//return nil, errors.New("未找到会员相应的微信登陆信息02")
			return nil, errors.New("getOpenId")
		}
		if mwModel.Openid == "" {
			//return nil, errors.New("当前会员未绑定微信")
			return nil, errors.New("getOpenId")
		}

		data.OpenID = mwModel.Openid
	}

	do, err := wxpay.Do(ctx, mch.UnifyOrder(&data))
	if err != nil {
		return nil, errors.New("统一下单失败：" + err.Error())
	}

	// 判断返回是否成功
	if !(do["result_code"] == "SUCCESS" && do["return_code"] == "SUCCESS") {
		// 有失败信息
		return nil, errors.New("统一下单失败：" + " err_code:" + do["err_code"] + " msg:" + do["err_code_des"])
	}
	result := map[string]string{}

	if tradeType == "JSAPI" {
		result = wxpay.JSAPI(do["prepay_id"])
	}

	if tradeType == "APP" {
		result = wxpay.APPAPI(do["prepay_id"])
	}

	// 保存到 pay_log
	_, err = toolsDb.GetUnSafaTable(ctx, "pay_log").InsertAndGetId(g.Map{
		"appid":          wxpay.AppID(),
		"mch_id":         wxpay.MchID(),
		"order_id":       outTradeNO,
		"payment_method": 1,
		"pay_type":       0,
		"open_id":        data.OpenID,
		"money":          data.TotalFee,
		"create_time":    tools.MakeTimestamp(),
	})
	if err != nil {
		return nil, errors.New("log失败：" + err.Error())
	}

	return result, nil
}

// tradeType 交易类型 ： 手机、PC、二维码、H5
func memberAlipay(ctx context.Context, orderModel *entity.Order, tradeType string) (map[string]string, error) {
	return nil, nil
}
